package cl.tinet.trainee.proyecto.dao;

import java.util.ArrayList;
import java.util.Date;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.apache.log4j.Logger;

import cl.tinet.trainee.proyecto.excepciones.DatosNulosException;
import cl.tinet.trainee.proyecto.modelo.Reserva;

/**
 * 
 * Implementacion de InterfazGenericaDAO para la tabla Usuario.
 * 
 * @author Jose Palma
 */
public class ReservaDAO implements InterfazReservaDAO {
    /**
     * Manejador de entidad.
     */
    private EntityManager em;

    /**
     * Log de la clase.
     */
    private static final Logger LOG = Logger.getLogger(ReservaDAO.class);

    /**
     * Constructor que inicializa el manejador de entidad em para cada objeto
     * UsuarioDAO creado.
     * 
     * @param em
     *            Manejador de entidad.
     */
    public ReservaDAO(EntityManager em) {
        this.em = em;
    }

    /**
     * {@inheritDoc}
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void agregar(Reserva nuevaReserva) {
        em.persist(nuevaReserva);
    }

    /**
     * {@inheritDoc}
     */
    public void borrar(Reserva reservaAEliminar) {
        if (reservaAEliminar != null) {
            em.remove(reservaAEliminar);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void actualizar(Reserva reservaAActualizar) {
        if (reservaAActualizar != null) {
            em.merge(reservaAActualizar);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @throws DatosNulosException
     *             Se activa cuando no encontro la reserva en la BD.
     */
    public Reserva buscar(Reserva reservaABuscar) throws DatosNulosException {
        Reserva reservaEncontrada = null;
        try {
            reservaEncontrada =
                    (Reserva) em
                            .createQuery(
                                    "SELECT R FROM Reserva R "
                                            + "WHERE R.usuario_username=:"
                                            + "usuario and R.sala_idsala=:sala"
                                            + " and R.fecha_inicio=:fecha")
                            .setParameter("usuario",
                                    reservaABuscar.getUsername())
                            .setParameter("sala", reservaABuscar.getSala())
                            .setParameter("fecha",
                                    reservaABuscar.getFechaInicio())
                            .getSingleResult();

        } catch (NoResultException e) {
            LOG.debug("BUSCANDO" + e.toString());
            throw new DatosNulosException(DatosNulosException.NO_EXISTEN_DATOS
                    + " Reserva id: " + reservaABuscar.getIdReserva());
        }
        return reservaEncontrada;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public ArrayList<Reserva> listar() {
        return ((ArrayList<Reserva>) em.createQuery("SELECT R FROM Reserva R")
                .getResultList());
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public ArrayList<Reserva> buscarPorFecha(Date fechaABuscar) {
        return ((ArrayList<Reserva>) em
                .createQuery(
                        "SELECT R FROM Reserva R "
                                + "WHERE R.fecha_inicio=:fecha")
                .setParameter("fecha", fechaABuscar).getResultList());
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public ArrayList<Reserva> buscarPorSala(int idsala) {
        return ((ArrayList<Reserva>) em
                .createQuery(
                        "SELECT R FROM Reserva R "
                                + "WHERE R.sala_idsala=:sala")
                .setParameter("sala", idsala).getResultList());
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public ArrayList<Reserva> buscarPorUsuario(int idusuario) {
        return ((ArrayList<Reserva>) em
                .createQuery(
                        "SELECT R FROM Reserva R "
                                + "WHERE R.usuario_username=:" + "usuario")
                .setParameter("usuario", idusuario).getResultList());
    }

}
